package com.famid.flashcards.data;

import java.util.ArrayList;
import java.util.List;
import com.famid.flashcards.data.Card.KnownStatus;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class CardsDAOImpl implements CardsDAO{
	
	private static final String TAG = CardsDAOImpl.class.getName();
	private SQLiteDatabase database;
	private CardDBHelper dbHelper;
	private String[] allColumns = { CardDBHelper.COLUMN_ID, CardDBHelper.COLUMN_QUESTION, CardDBHelper.COLUMN_ANSWER, CardDBHelper.COLUMN_STATUS, CardDBHelper.COLUMN_STACK_ID };
	
	public CardsDAOImpl(Context context) {
		dbHelper = new CardDBHelper(context);
	}

	@Override
	public void open() throws SQLException {
		database = dbHelper.getWritableDatabase();
	}

	@Override
	public void close() {
		dbHelper.close();
	}

	@Override
	public Card createCard(Card card) {
		ContentValues values = new ContentValues();
		values.put(CardDBHelper.COLUMN_QUESTION, card.getQuestion());
		values.put(CardDBHelper.COLUMN_ANSWER, card.getAnswer());
		values.put(CardDBHelper.COLUMN_STATUS, card.getStatus().toString());
		values.put(CardDBHelper.COLUMN_STACK_ID, card.getStuckId());
		
		Log.d(TAG, "Insert new card, q: "+ card.getQuestion()+" ,a: "+card.getAnswer());
		long insertId = database.insert(CardDBHelper.TABLE_CARDS, null,	values);
		
		// To show how to query
		Cursor cursor = database.query(CardDBHelper.TABLE_CARDS,
				allColumns, CardDBHelper.COLUMN_ID + " = " + insertId, null,
				null, null, null);
		cursor.moveToFirst();
		return cursorToCard(cursor);
	}

	@Override
	public void deleteCard(Card card) {
		long id = card.getId();
		Log.d(TAG, "Delete card with id: " + id);
		database.delete(CardDBHelper.TABLE_CARDS, CardDBHelper.COLUMN_ID + " = " + id, null);
	}

	@Override
	public List<Card> getAllCards() {
		List<Card> cards = new ArrayList<Card>();
		Log.d(TAG, "Get all cards.");
		Cursor cursor = database.query(CardDBHelper.TABLE_CARDS, allColumns, null, null, null, null, null);
		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Card comment = cursorToCard(cursor);
			cards.add(comment);
			cursor.moveToNext();
		}
		// Make sure to close the cursor
		cursor.close();
		Log.d(TAG, "Result size: "+cards.size());
		return cards;
	}

	private Card cursorToCard(Cursor cursor) {
		long id = cursor.getLong(0);
		String question = cursor.getString(1);
		String answer = cursor.getString(2);
		KnownStatus status = Enum.valueOf(KnownStatus.class, cursor.getString(3));
		long stuckId = cursor.getLong(4);
		
		Card card = new Card(id, question, answer, status, stuckId);
		return card;
	}

	@Override
	public List<Card> getAllCardsForStack(long id) {
		List<Card> cards = new ArrayList<Card>();
		Log.d(TAG, "Get cards for stack id: "+id);
		Cursor cursor = database.query(CardDBHelper.TABLE_CARDS, allColumns, CardDBHelper.COLUMN_STACK_ID + " = " +  id, null, null, null, null);
		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Card comment = cursorToCard(cursor);
			cards.add(comment);
			cursor.moveToNext();
		}
		// Make sure to close the cursor
		cursor.close();
		Log.d(TAG, "Result size: "+cards.size());
		return cards;
	}

	@Override
	public Card get(long id) {
		Log.d(TAG, "Get single card id: "+id);
		Cursor cursor = database.query(CardDBHelper.TABLE_CARDS,
				allColumns, CardDBHelper.COLUMN_ID + " = " + id, null,
				null, null, null);
		cursor.moveToFirst();
		return cursorToCard(cursor);
	}

	@Override
	public Card update(Card card) {
		Log.d(TAG, "Update card id: "+card.getId());
		ContentValues values = new ContentValues();
		values.put(CardDBHelper.COLUMN_QUESTION, card.getQuestion());
		values.put(CardDBHelper.COLUMN_ANSWER, card.getAnswer());
		values.put(CardDBHelper.COLUMN_STATUS, card.getStatus().toString());
		values.put(CardDBHelper.COLUMN_STACK_ID, card.getStuckId());
		
		database.update(CardDBHelper.TABLE_CARDS, values, CardDBHelper.COLUMN_ID + " = " + card.getId(), null);
		return get(card.getId());
	}

	@Override
	public int countByStack(long stackId) {
		List<Card> cards = new ArrayList<Card>();
		Log.d(TAG, "Count cards for stack id: "+stackId);
		Cursor cursor = database.query(CardDBHelper.TABLE_CARDS,  (new String[] {CardDBHelper.COLUMN_ID}), CardDBHelper.COLUMN_STACK_ID + " = " + stackId, null, null, null, null);
		int count = cursor.getCount();
		// Make sure to close the cursor
		cursor.close();
		Log.d(TAG, "Result size: "+count);
		return count;
	}

	@Override
	public void deleteForStack(long stackId) {
		Log.d(TAG, "Delete all cards for stack: "+stackId);
		int deleted = database.delete(CardDBHelper.TABLE_CARDS, CardDBHelper.COLUMN_STACK_ID + " = " + stackId, null);
		Log.d(TAG, "Delete "+deleted+" cards for stack: "+stackId);
	}
}
